home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-06 | 24.5 KB | 507 lines | [TEXT/MPS ] |
- // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
- // UDiscListView.cp
-
- #include "UDiscListView.h"
- #include "UDiscList.h"
- #include "UDiscListCmds.h"
- #include "UBinariesCmds.h"
- #include "UPostArticleCmds.h"
- #include "NetAsciiTools.h"
- #include "UNewsAppl.h"
- #include "UGroupDoc.h"
- #include "UThread.h"
- #include "UPrefsDatabase.h"
- #include "URowSelection.h"
- #include "UTextScroller.h"
- #include "ViewTools.h"
- #include "Tools.h"
-
- #include <RsrcGlobals.h>
- #include <ErrorGlobals.h>
-
- #include <Packages.h>
- #include <ToolUtils.h>
-
- #pragma segment MyGroup
-
- #define qPrintDottedLine 1
-
- #define qDebugArticleIterator qDebug & 0
-
- //-------------------------------------------------------------------
- const short kSeparatorHeight = 2; // should be in 'View'
- const short kExtraHeight = 2;
-
- CStr255 gNewString, gSeenString, gReadString, gExpiredSubjectString, gExpiredAuthorString;
- Boolean gHasFetchedStatusStrings = false;
-
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- class CDiscListArticleIterator : public CIterator
- {
- public:
- CDiscListArticleIterator(TDiscListView *dlv, GridCell cell);
- ~CDiscListArticleIterator();
-
- long FirstArticleID();
- Boolean More();
- long NextArticleID();
- ArrayIndex GetIndex();
- Boolean ArticleIsAvaible();
-
- void GetArticleVRects(CRect &subjectRect, CRect &statusRect, CRect &authorRect);
- protected:
- void Advance();
-
- private:
- TDiscListView *fDiscListView;
- PDiscList *fDiscList;
- ArrayIndex fDiscIndex;
- ArrayIndex fNoArticles, fArticleIndex;
- long fArticleID;
- CRect fCellRect;
- };
-
- CDiscListArticleIterator::CDiscListArticleIterator(TDiscListView *dlv, GridCell cell)
- {
- fDiscListView = dlv;
- fDiscList = dlv->fDiscList;
- VRect vr;
- dlv->CellToVRect(cell, vr);
- dlv->ViewToQDRect(vr, fCellRect);
- fDiscIndex = dlv->fDiscIndexList->At(cell.v);
- fNoArticles = fDiscList->GetNoArticles(fDiscIndex);
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: Constructor, cellRect = %s, discIndex = %ld, noArticles = %ld\n", (char*)fCellRect, fDiscIndex, fNoArticles);
- #endif
- }
-
- CDiscListArticleIterator::~CDiscListArticleIterator()
- {
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: Destruct\n");
- #endif
- }
-
- long CDiscListArticleIterator::FirstArticleID()
- {
- fArticleIndex = 0;
- Advance();
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: returned %ld as first article id\n", fArticleID);
- #endif
- return fArticleID;
- }
-
- Boolean CDiscListArticleIterator::More()
- {
- return fArticleIndex <= fNoArticles;
- }
-
- long CDiscListArticleIterator::NextArticleID()
- {
- if (More())
- Advance();
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: returns %ld as next article id\n", fArticleID);
- #endif
- return fArticleID;
- }
-
- void CDiscListArticleIterator::Advance()
- {
- ++fArticleIndex;
- if (!More())
- return;
- fArticleID = fDiscList->GetArticleID(fDiscIndex, fArticleIndex);
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: Advance: new fArticleIndex = %ld, new fArticleID = %ld\n", fArticleIndex, fArticleID);
- #endif
- }
-
- ArrayIndex CDiscListArticleIterator::GetIndex()
- {
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: GetIndex() returns %ld\n", fArticleIndex);
- #endif
- return fArticleIndex;
- }
-
- Boolean CDiscListArticleIterator::ArticleIsAvaible()
- {
- return fArticleID >= fDiscListView->fFirstAvaibleID && fArticleID <= fDiscListView->fLastAvaibleID;
- }
-
- void CDiscListArticleIterator::GetArticleVRects(CRect &subjectRect, CRect &statusRect, CRect &authorRect)
- {
- short top = fCellRect.top + kSeparatorHeight;
- top += (short(fArticleIndex) - 1) * fDiscListView->fGridViewTextStyle.fRowHeight;
- short bottom = top + fDiscListView->fGridViewTextStyle.fRowHeight;
- subjectRect.top = statusRect.top = authorRect.top = top;
- subjectRect.bottom = statusRect.bottom = authorRect.bottom = bottom;
-
- short h = fDiscListView->fGridViewTextStyle.fHorzOffset;
- short col1 = h;
- short col2 = col1 + fDiscListView->fSubjectWidth;
- short col3 = col2 + 2 * h;
- subjectRect.left = col1;
- subjectRect.right = col2 - h;
- if (fArticleIndex > 1)
- subjectRect.left += fDiscListView->fSubjectHorzOffset;
- statusRect.left = col2;
- statusRect.right = col3;
- authorRect.left = col3;
- authorRect.right = short(fDiscListView->fSize.h);
- #if qDebugArticleIterator
- fprintf(stderr, "DLAI: GetRects, subject = %s, ", (char*)subjectRect);
- fprintf(stderr, "status = %s, ", (char*)statusRect);
- fprintf(stderr, "author = %s\n", (char*)authorRect);
- #endif
- }
-
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- TDiscListView::TDiscListView()
- {
- }
-
- pascal void TDiscListView::Initialize()
- {
- inherited::Initialize();
- fDoc = nil;
- fWindow = nil;
- fArticleStcleSeen); // test
-
- HandleOffsetLength hol;
- CStr255 subject("");
- if (fDoc->GetSubject(id, hol))
- CopyHolToCStr255(hol, subject);
-
- short i = subject.Length();
- while (i && subject[i] <= 32)
- --i;
- subject.Length() = i;
- while (i && subject[1] <= 32)
- {
- subject.Delete(1, 1); // expensive but seldom
- --i;
- }
-
- Boolean drawSubject;
- if (iter.GetIndex() == 1)
- drawSubject = true;
- else
- {
- drawSubject = (subject != lastSubject);
- if (drawSubject)
- {
- if (subject.Length() > 4 && subject[1] == 'R' && subject[2] == 'e' && subject[3] == ':')
- {
- i = (subject[4] == 32) ? 5 : 4;
- while (subject.Length() >= 5 && subject[5] <= 32)
- subject.Delete(5, 1);
- if (
- subject.Length() == lastSubject.Length() + 4 &&
- EqualBlocks(Ptr(&subject[5]), Ptr(&lastSubject[1]), lastSubject.Length()))
- {
- drawSubject = false; // ignore "Re: "
- }
- else if (
- subject.Length() + 4 == lastSubject.Length() &&
- EqualBlocks(Ptr(&subject[1]), Ptr(&lastSubject[5]), subject.Length()))
- {
- drawSubject = false; // ignore removed "Re: "
- }
- }
- }
- }
-
- lastSubject = subject;
- if (drawSubject)
- {
- MoveTo(subjectRect.left, v);
- TruncString(subjectRect.GetLength(hSel), subject, smTruncMiddle);
- DrawString(subject);
- }
-
- MoveTo(statusRect.left, v);
- ArticleStatus stat = fOldArticleStatus->GetStatus(id);
- // ArticleStatus stat = fArticleStatus->GetStatus(id);
- if (stat == kArticleNew)
- DrawString(gNewString);
- else if (stat == kArticleSeen)
- DrawString(gSeenString);
- else
- DrawString(gReadString);
-
- MoveTo(authorRect.left, v);
- CStr255 email;
- if (fDoc->GetFrom(id, hol))
- {
- CStr255 text;
- CopyHolToCStr255(hol, text);
- GetPrintableAuthorName(text, s, email);
- }
- else
- s = gExpiredAuthorString;
- DrawString(s);
- #if qDebug
- DrawString(", ");
- NumToString(id, s);
- DrawString(s);
- #endif
- }
- }
-
- pascal void TDiscListView::DrawRangeOfCells(GridCell startCell,
- GridCell stopCell,
- const VRect &aRect)
- {
- TextStyle itsTextStyle = fGridViewTextStyle.fTextStyle;
- SetPortTextStyle(itsTextStyle);
- inherited::DrawRangeOfCells(startCell, stopCell, aRect);
- }
-
- //================================================================================================
- void TDiscListView::HighlighOneCell(GridCell aCell, HLState fromHL, HLState toHL)
- {
- VRect vr;
- CellToVRect(aCell, vr);
- CRect r;
- ViewToQDRect(vr, r);
- r.top += kSeparatorHeight - 1; // -1 ??
- // r.bottom -= 1;
- PenNormal();
- PenMode(patXor);
- UseSelectionColor();
- switch (fromHL + toHL)
- {
- case hlOnDim:
- case hlOffOn:
- InvertRect(r);
- break;
- /*
- case hlOnDim:
- r.Inset(CPoint(1, 1));
- InvertRect(r);
- break;
-
- case hlOffDim:
- FrameRect(r);
- break;
-
- case hlOffOn:
- InvertRect(r);
- break;
- */
- }
- }
-
- pascal void TDiscListView::HighlightCells(RgnHandle theCells,
- HLState fromHL,
- HLState toHL)
- {
- if (fromHL == toHL)
- return;
- Focus();
- switch (fromHL + toHL)
- {
- case hlOffDim:
- case hlOnDim:
- case hlOffOn:
- {
- CCellInRegionIterator iter(this, theCells);
- for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- HighlighOneCell(aCell, fromHL, toHL);
- }
- break;
- }
- }
-
-
- //================================================================================================
- Boolean TDiscListView::FindHelp(const VPoint &localPoint, VRect &helpRect, short &balloonVariant)
- {
- GridCell aCell = VPointToCell(localPoint);
- CDiscListArticleIterator iter(this, aCell);
- CPoint pt = localPoint.ToPoint();
- for (long id = iter.FirstArticleID(); iter.More(); id = iter.NextArticleID())
- {
- CRect subjectRect, statusRect, authorRect;
- iter.GetArticleVRects(subjectRect, statusRect, authorRect);
- if (pt.v < subjectRect.top)
- {
- helpRect.left = 0;
- helpRect.right = fSize.h;
- helpRect.top = 0;
- helpRect.bottom = subjectRect.top;
- fHelpIndex = 1;
- balloonVariant = kHMEnabledItem;
- return false;
- }
-
- if (iter.ArticleIsAvaible())
- balloonVariant = kHMEnabledItem;
- else
- balloonVariant = kHMDisabledIted())
- {
- aCell = LastSelectedCell();
- aCell.v++;
- }
- else
- aCell = GridCell(1, 1);
- if (aCell.v <= fNumOfRows)
- {
- SelectCell(aCell, false, true, true);
- ScrollSelectionIntoView(kRedraw);
- Focus();
- Update();
- }
- }
- break;
-
- case chBackspace:
- SetEmptySelection(kRedraw); // should be KILL one day
- break;
-
-
- default:
- inherited::DoKeyEvent(event);
- }
- }
-
- pascal void TDiscListView::DoMouseCommand(VPoint &theMouse,
- TToolboxEvent *event, CPoint /* hysteresis */ )
- {
- GridCell aCell;
- if (IdentifyPoint(theMouse, aCell) == badChoice)
- return;
- if (event->fClickCount > 1 && IsAnyCellSelected())
- OpenSelection();
- else // not double-click
- {
- TStickySelectCommand *aCommand = new TStickySelectCommand();
- aCommand->IStickySelectCommand(this, theMouse, event->IsShiftKeyPressed(), event->IsCommandKeyPressed());
- PostCommand(aCommand);
- }
- }
-
-
- pascal void TDiscListView::DoMenuCommand(CommandNumber aCommandNumber)
- {
- if (!IsEnabled())
- {
- inherited::DoMenuCommand(aCommandNumber);
- return;
- }
- switch (aCommandNumber)
- {
- case cShowAllDiscussions:
- if (fDiscToShow != kShowAllDiscs)
- {
- fDiscToShow = kShowAllDiscs;
- UpdateList();
- }
- break;
-
- case cShowOnlyTodayDiscussions:
- if (fDiscToShow != kShowTodaysDiscs)
- {
- fDiscToShow = kShowTodaysDiscs;
- UpdateList();
- }
- break;
-
- case cShowDiscsWithUnreadArticles:
- if (fDiscToShow != kShowDiscsWithUnreadArticles)
- {
- fDiscToShow = kShowDiscsWithUnreadArticles;
- UpdateList();
- }
- break;
-
- case cShowDiscsWithNewArticles:
- if (fDiscToShow != kShowDiscsWithNewArticles)
- {
- fDiscToShow = kShowDiscsWithNewArticles;
- UpdateList();
- }
- break;
-
- case cSave:
- case cSaveAs:
- case cSaveCopy:
- {
- TSaveArticlesCommand *aCommand = new TSaveArticlesCommand();
- aCommand->ISaveArticlesCommand(cSaveAs, fDoc, GetListOfSelectedArticles());
- gApplWideThreads->ExecuteCommand(aCommand, "TSaveArticlesCommand (TDiscListView)");
- }
- break;
-
- case cExtractBinaries:
- ExtractBinaries(cExtractBinaries, fDoc, GetListOfSelectedArticles());
- break;
-
- case cPostNewDiscussion:
- TCreateNewDiscussionCommand *command = new TCreateNewDiscussionCommand();
- command->ICreateNewDiscussionCommand(fDoc);
- PostCommand(command);
- break;
-
- case cMarkThreadAsNew:
- MarkSelectionAs(kArticleNew);
- break;
-
- case cMarkThreadAsSeen:
- MarkSelectionAs(kArticleSeen);
- break;
-
- case cMarkThreadAsRead:
- MarkSelectionAs(kArticleRead);
- break;
-
- default:
- {
- StandardGridViewTextStyle gvts = fGridViewTextStyle;
- if (gNewsAppl->HandleFontMenu(aCommandNumber, gvts.fTextStyle))
- {
- CalcStandardGridViewFont(gvts);
- fGridViewTextStyle = gvts;
- gPrefs->SetTextStylePrefs('TSdi', gvts.fTextStyle);
- ChangedFont();
- }
- else
- inherited::DoMenuCommand(aCommandNumber);
- }
- }
- }
-
- pascal void TDiscListView::DoSetupMenus()
- {
- Boolean lowSpace = MemSpaceIsLow();
- gNewsAppl->EnableFontMenu(fGridViewTextStyle.fTextStyle);
- Boolean gotSelection = IsAnyCellSelected();
- Enable(cExtractBinaries, !lowSpace && gotSelection);
- if (gPrefs->GetBooleanPrefs('BiAs'))
- SetMenuState(cExtractBinaries, kDynamicMenuItemNames, kExtractAsMenuItemText, kExtractAsMultipleAsMenuItemText, IsOptionKeyDown());
- else
- SetMenuState(cExtractBinaries, kDynamicMenuItemNames, kExtractMenuItemText, kExtractAsMultipleMenuItemText, IsOptionKeyDown());
-
- Enable(cMarkThreadAsNew, gotSelection);
- Enable(cMarkThreadAsSeen, gotSelection);
- Enable(cMarkThreadAsRead, gotSelection);
-
- Enable(cSelectAll, true);
-
- Enable(cPostNewDiscussion, !lowSpace);
-
- EnableCheck(cShowAllDiscussions, true, fDiscToShow == kShowAllDiscs);
- EnableCheck(cShowOnlyTodayDiscussions, true, fDiscToShow == kShowTodaysDiscs);
- EnableCheck(cShowDiscsWithUnreadArticles, true, fDiscToShow == kShowDiscsWithUnreadArticles);
- EnableCheck(cShowDiscsWithNewArticles, true, fDiscToShow == kShowDiscsWithNewArticles);
-
- inherited::DoSetupMenus();
- Enable(cSave, gotSelection);
- Enable(cSaveAs, false);
- Enable(cSaveCopy, gotSelection);
- Enable(cRevert, false);
- }
-